package org.hs.phd.common.improc.traversal;

import static com.googlecode.javacv.cpp.opencv_core.cvCopy;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;

import com.googlecode.javacv.cpp.opencv_core;
import com.googlecode.javacv.cpp.opencv_core.IplImage;

class RGBImageRectangularTraverser implements RGBImagePixelTraverser {
	
	private final Rectangle rectInitial;

	public RGBImageRectangularTraverser(Rectangle rect) {
		this.rectInitial = rect;
	}

	@Override
	public void traversePixels(IplImage frame, RGBImagePixelProcessor processor) {
		assert frame.getBufferedImageType() == BufferedImage.TYPE_3BYTE_BGR;
		
		Rectangle rect = rectInitial.intersection(new Rectangle(0,0, frame.width(), frame.height()));
		
		int[] rgbs = getImageRGBs(frame, rect);

		
		for(int j = 0; j < rect.height; j++){
			for(int i = 0; i < rect.width; i++){

				int baseIndex = i + j*rect.width;
				
				int rgb = rgbs[ baseIndex ];
				int nB = rgb & 0xFF;
				int nG = (rgb >> 8) & 0xFF;
				int nR = (rgb >> 16) & 0xFF;
				
				processor.processPixel(i + rect.x, j + rect.y, nR, nG, nB);
			
			}
		}
	}

	private int[] getImageRGBs(IplImage frame, Rectangle rect) {
		opencv_core.cvSetImageROI(frame, opencv_core.cvRect(rect.x, rect.y, rect.width, rect.height));
		IplImage croppedImage = opencv_core.cvCreateImage(opencv_core.cvSize(rect.width, rect.height), frame.depth(), frame.nChannels());
		cvCopy(frame, croppedImage);
		opencv_core.cvResetImageROI(frame);

		BufferedImage bufferedImage = croppedImage.getBufferedImage();
		int[] rgbs = new int[rect.height*rect.width];
		bufferedImage.getRGB(0, 0, rect.width, rect.height, rgbs, 0, rect.width);

		opencv_core.cvReleaseImage(croppedImage);
		return rgbs;
	}

}
